package com.itlong.cloud.property.service.impl;

import com.itlong.cloud.POJO.DTO.property.PropertyFunctionGetPageDTO;
import com.itlong.cloud.POJO.PO.PropertyFunctionPO;
import com.itlong.cloud.POJO.VO.property.PropertyFunctionVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.enumerate.DataStatusEnum;
import com.itlong.cloud.property.dao.IPropertyFunctionDao;
import com.itlong.cloud.property.service.IPropertyFunctionService;
import com.itlong.cloud.utils.data.handler.SqlUtil;
import com.itlong.cloud.utils.page.Page;
import com.itlong.cloud.utils.random.LogicIdUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * <desc>
 *      物业-菜单资源业务处理接口实现类
 * </desc>
 *
 * @createDate 2017/09/21
 */
@Service
public class PropertyFunctionServiceImpl implements IPropertyFunctionService{

    private static final Logger LOG = LoggerFactory.getLogger(PropertyFunctionServiceImpl.class);
    @Autowired
    IPropertyFunctionDao iPropertyFunctionDao;




    /**
     * <desc>
     *      保存资源
     * </desc>
     * @param propertyFunctionPO 资源实体
     * @return  sql执行行数
     * @author Biao.R
     * @createDate 2017/10/16
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public Integer save(PropertyFunctionPO propertyFunctionPO) throws Exception {
        propertyFunctionPO.setFunctionId(LogicIdUtil.bussinessId());
        propertyFunctionPO.setCreateTime(new Date());
        propertyFunctionPO.setStatus(DataStatusEnum.NORMAL.getType());
        return iPropertyFunctionDao.save(SqlUtil.durableData(propertyFunctionPO, PlatformConstants.TABLE_SAVE));
    }


    /**
     * <desc>
     *      更新资源
     * </desc>
     * @param propertyFunctionPO 资源实体
     * @return sql执行行数
     * @author Biao.R
     * @createDate 2017/10/16
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public Integer update(PropertyFunctionPO propertyFunctionPO) throws Exception {
        propertyFunctionPO.setUpdateTime(new Date());
        return iPropertyFunctionDao.update(SqlUtil.durableData(propertyFunctionPO,PlatformConstants.TABLE_UPDATE));
    }

    /**
     * <desc>
     *      通过id获取资源
     * </desc>
     * @param propertyFunctionPO 资源实体
     * @return 资源实体
     * @author Biao.R
     * @createDate 2017/10/16
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public PropertyFunctionPO getOne(PropertyFunctionPO propertyFunctionPO) {
        return iPropertyFunctionDao.getOne(propertyFunctionPO);
    }

    /**
     * <desc>
     *      获取所有资源
     * </desc>
     * @return 资源结果集
     * @author Biao.R
     * @createDate 2017/10/16
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<PropertyFunctionPO> getList() {
        return iPropertyFunctionDao.getList();
    }

    /**
     * <desc>
     *      获取分页数据
     * </desc>
     * @param pageDTO 查询参数DTO
     * @return page模型
     * @author Biao.R
     * @createDate 2017/10/16
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public Page<PropertyFunctionPO> getPage(PropertyFunctionGetPageDTO pageDTO) throws Exception {
        //将DTO转换为Map params
        Map<String, Object> params = SqlUtil.convertBeanToMapParams(pageDTO);
        //分页类默认pageSize为20
        Page<PropertyFunctionPO> page = new Page<>();
        page.getPage().setPageSize(pageDTO.getPageSize());
        page.getPage().setCurrentPage(pageDTO.getCurrentPage());
        params.put("currentPage",page.getPage().getStartSlip());
        params.put("pageSize",page.getPage().getPageSize());
        //填充返回数据集
        page.setRows(iPropertyFunctionDao.getPage(params), iPropertyFunctionDao.getPageCount(params));
        return page;
    }

    /**
     * <desc>
     *      删除资源
     * </desc>
     * @param functionIds 资源id数组
     * @return sql执行行数
     * @author Biao.R
     * @createDate 2017/10/16
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public Integer delete(String functionIds) {
        String functionId[] = StringHandlerUtil.splitString(functionIds);
        return iPropertyFunctionDao.delete(functionId,new Date());
    }

    /**
     * <desc>
     *      获取下级集合
     * </desc>
     * @param functionId 资源id
     * @return 子级结果集
     * @author Biao.R
     * @createDate 2017/10/16
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<PropertyFunctionVO> getChilds(String functionId) {
        List<PropertyFunctionVO> roots=iPropertyFunctionDao.getChildsByParent(functionId);
        roots.forEach(child->{
            List<PropertyFunctionVO> list = iPropertyFunctionDao.getChildsByParent(child.getFunctionId());
            if(list != null && !list.isEmpty()){
                child.setHaveChild("true");
            }
        });
        return roots;
    }

    /**
     * <desc>
     *      根据角色获取分配菜单所有节点
     * </desc>
     * @param   roleId  查询的角色ID
     * @param   projectId  查询的项目ID
     * @return  查询到的菜单对象集合
     * @author Biao.R
     * @createDate 2017/10/16
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<PropertyFunctionVO> getAllotFunction(String roleId,String projectId){
        List<PropertyFunctionVO> roots = iPropertyFunctionDao.getChildsByParent("0");

        //参数为空时获取所有物业菜单
        List<String> roleFunctions = null;
        if (StringUtils.isBlank(roleId) || StringUtils.isBlank(projectId)){
            roleFunctions = new ArrayList<>();
        }else {
            Map<String,Object> params = new HashMap<>();
            params.put("roleId",roleId);
            params.put("projectId",projectId);
            roleFunctions = iPropertyFunctionDao.getFunctionIdsByRole(params);
        }
        roots = recursionFunction(roots,roleFunctions);
        return roots;
    }

    /**
     * <desc>
     * 通过角色id及项目id获取该角色拥有的所有节点ID
     * </desc>
     *
     * @param roleId    角色id
     * @param projectId 项目id
     * @return
     * @author Chunjian.G
     * @createDate 2018-01-15
     */
    @Override
    public List<String> getFunctionIdsByRoleProject(String roleId, String projectId) throws Exception {
        Map<String,Object> params = new HashMap<>();
        params.put("roleId",roleId);
        params.put("projectId",projectId);
        return iPropertyFunctionDao.getFunctionIdsByRole(params);
    }

    /**
     * <desc>
     *      获取当前节点的父级节点以及同级别所有父级节点
     * </desc>
     * @param       parent 资源id
     * @return      查询到的菜单对象集合
     * @author Biao.R
     * @createDate 2017/10/16
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<PropertyFunctionPO> getParentLevelFunctions(String parent) {
        PropertyFunctionPO propertyFunctionPO=iPropertyFunctionDao.getParent(parent);
        try {
            List<PropertyFunctionPO> parents = iPropertyFunctionDao.getParentLevelFunctions(propertyFunctionPO.getParent());
            return parents;
        }catch (Exception e){
            return null;
        }
    }

    /**
     * <desc>
     *      递归获取所有节点 并查询角色是否已有该节点
     * </desc>
     * @param   roots 菜单集合
     * @param   roleFunctions  角色菜单关系集合
     * @return  组合标记后的菜单集合
     * @author Biao.R
     * @createDate 2017/10/16
     */
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<PropertyFunctionVO> recursionFunction(List<PropertyFunctionVO> roots,List<String> roleFunctions){
        roots.forEach(child->{
            List<PropertyFunctionVO> list = iPropertyFunctionDao.getChildsByParent(child.getFunctionId());
            //遍历roleFunctions查找第一个与child functionId相同的值，将child的haveAuth设为true
            if(roleFunctions.stream().filter(rf ->
                            rf.equals(child.getFunctionId())
                            ).findFirst().isPresent()){
                child.setHaveAuth("true");
            }
            if(list != null && list.size()>0){
                //遍历菜单节点与角色菜单判断是否已存在
                list.forEach(function->{
                    if(roleFunctions.stream().filter(rf ->
                                    rf.equals(function.getFunctionId())
                                    ).findFirst().isPresent()){
                        function.setHaveAuth("true");
                    }
                });
                child.setHaveChild("true");
                child.setChilds(this.recursionFunction(list,roleFunctions));
            }
        });
        return roots;
    }


    /**
     * <desc>
     *      1.6版本菜单变更
     * </desc>
     *
     * @return
     * @author Jiaqi.X
     * @createDate 2018/04/18
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public Boolean handleV16FunctionUpdate(){
        //查询所有拥有该资源的角色
        List<Map<String,Object>> roles = iPropertyFunctionDao.getUpdateRole();
        //初始化所有需要替换的新权限
        String[] functionId = new String[]{"673025752576458752","673025893043699712","673026007929880576",
        "673026108140191744","673026274603728896","673026376923774976","673026470028935168","673026556096053248",
        "673026626531000320","673028682335551488","673029298596249600","673029381475696640","673029460748042240",
        "673029768530264064","673029870942584832","673029950319788032","673030069282832384","673030143886917632",
        "673030247360397312","679842136203624448"};
        List<String> oldRoles = new ArrayList<>();
        for(Map<String,Object> role : roles){
            iPropertyFunctionDao.updateV16RoleFunctions(role.get("role_id").toString(),
                    role.get("project_id").toString(),functionId);
            oldRoles.add(role.get("id").toString());
        }
        String[] deleteFunction = oldRoles.toArray(new String[oldRoles.size()]);
        //删除roles
        if(!oldRoles.isEmpty()){
            iPropertyFunctionDao.deleteV16RoleFunctions(deleteFunction);
            //删除旧设备管理菜单
            iPropertyFunctionDao.deleteOldDeviceFunction();
        }
        return true;
    }

    /**
     * <desc>
     *      根据套餐id获取物业功能
     * </desc>
     *
     * @param propertyPackageId 物业套餐id，多个逗号隔开
     * @return
     * @Author Zhu.yj
     * @createDate  2020/3/25
     */
    public List<PropertyFunctionVO> getPackageFunction(String propertyPackageId){
        List<PropertyFunctionVO> roots = iPropertyFunctionDao.getChildsByParent("0");
        List<String> packageFunctionList = iPropertyFunctionDao.getFunctionByPackage(StringHandlerUtil.splitStringList(propertyPackageId));
        roots = recursionFunction(roots,packageFunctionList);
        return roots;
    }
}
